/********************************************
* Copyrigt (C) rumi
* Module: View_UartUI.h
*********************************************/
#ifndef View_UartUI_H
#define View_UartUI_H

#include <QWidget>
#include <QPushButton>
#include <QGroupBox>
#include <QGridLayout>
#include <QComboBox>
#include <QLabel>
#include <QPlainTextEdit>
#include <QTextEdit>
#include <QDir>
#include <QTextStream>
#include <QCoreApplication>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QDebug>
#include <QTimer>
#include <QThread>
#include <QMutex>
#include <QQueue>

//#define Uart_DEBUG
#define Uart_ShowUartSpeed

// *****************************************
// Send thread
// *****************************************
class SendThread : public QThread {
    Q_OBJECT
public:
    explicit SendThread(QObject *parent = nullptr) : QThread(parent) {}
    void enqueueData(const QString &data) {
        QMutexLocker locker(&mutex);
        queue.enqueue(data);
    }

    void stop() {
        QMutexLocker locker(&mutex);
        running = false;
    }

signals:
    void sendData(const QString &data); // notice main thread to read data 

protected:
    void run() override {
        while (running) {
            QMutexLocker locker(&mutex);
            if (!queue.isEmpty()) {
                QString data = queue.dequeue();
                locker.unlock();
                emit sendData(data);
            }
            //msleep(100); 
        }
    }

private:
    QQueue<QString> queue;
    QMutex mutex;
    bool running = true;
};

// *****************************************
// Recive thread
// *****************************************
class ReceiveThread : public QThread {
    Q_OBJECT
public:
    explicit ReceiveThread(QObject *parent = nullptr) : QThread(parent) {}

    void stop() {
        QMutexLocker locker(&mutex);
        running = false;
    }

signals:
    void requestRead(); // notice main thread to read data

protected:
    void run() override {
        while (running) {
            emit requestRead(); // set a timer to request to read 
            msleep(50); 
        }
    }

private:
    QMutex mutex;
    bool running = true;
};

// *****************************************
// view thread
// *****************************************
class View_UartUI : public QWidget {
    Q_OBJECT

public:
    View_UartUI(QWidget *parent = nullptr);

private:
    QSerialPort *serialPort;
    QTimer *updateTimer;
    QLabel *Uart_Info_label[5];
    QComboBox *Uartwidget_Info_ComboBox[5];
    QPushButton *Uartwidget_Info_PushButton[3];
    QPlainTextEdit *Uartwidget_TR_PlainTextEdit;
    QTextEdit *Uartwidget_TR_TextEdit;
    SendThread *sendThread;
    ReceiveThread *receiveThread;
signals:
    void switchToViewMain();
private slots:
    void updateAvailablePorts();
    void openSerialPort();
    void sendSerialData();
    void readSerialData();
    void clearSerialRecv();
    void clearSerialSend();
    void writeSerialData(const QString &data);
    void reciveSerialData();
};


#endif
/********************************************
 * End of file
*********************************************/
